﻿#define _CRT_SECURE_NO_WARNINGS 1
//大小端字节序
//#include<stdio.h>
//
//int main()
//{
//	int a = 0x11223344;
//
//	return 0;
//}

//写一个大小端字节序的判断
//#include<stdio.h>
//
//int BigSmallEnds()
//{
//	int a = 1;
//	char* pa = &a;
//	if (*pa == 1)
//	{
//		return 1;//小端
//	}
//	else
//	{
//		return 0;//大端
//	}
//}
//
//int main()
//{
//
//	if (BigSmallEnds())
//	{
//		printf("小端\n");
//	}
//	else
//	{
//		printf("大端\n");
//	}
//
//	return 0;
//}

//结构的声明
//struct S
//{
//	int a;
//}s1;

//结构体变量的创建和初始化
//#include<stdio.h>
//
//struct S
//{
//	char name[20];
//	int age;
//	double grades;
//};
//
//int main()
//{
//	struct S s1 = {"张三", 20, 53.5};//结构体的创建和初始化
//
//	return 0;
//}

//结构体的特殊声明
//匿名结构体声明
//只能在全局创建一次，后序不能在进行创建
//struct
//{
//	int a;
//}s;

//结构的⾃引⽤
//struct S
//{
//	int a;
//	char ch;
//};
//
//struct Ps
//{
//	int b;
//	char cc;
//	struct S s;//在一个结构体内引用另外一个结构体作为成员变量，称为结构体的自引用
//};

//结构体的内存对齐
//#include<stdio.h>
////练习1
//struct S1
//{
//	char c1;//1 8 1
//	int i;  //4 8 4
//	char c2;//1 8 1
//};
//
////练习2
//struct S2
//{
//	char c1;
//	char c2;
//	int i;
//};
//
////练习3
//struct S3
//{
//	double d;
//	char c;
//	int i;
//};
//
////练习4-结构体嵌套问题
//struct S4
//{
//	char c1;
//	struct S3 s3;
//	double d;
//};
//
//
//int main()
//{
//	printf("%d\n", sizeof(struct S1));//12
//	printf("%d\n", sizeof(struct S2));//8
//	printf("%d\n", sizeof(struct S3));//16
//	printf("%d\n", sizeof(struct S4));//32
//
//	return 0;
//}

//结构体传参
//#include<stdio.h>
//
//typedef struct Stu
//{
//	char name[20];
//	size_t age;
//	double fraction;
//}Stu;
//
//void Print1(Stu s)
//{
//	printf("%s %zd %.2lf\n", s.name, s.age, s.fraction);
//}
//
//void Print2(Stu* s)
//{
//	printf("%s %zd %.2lf\n", s->name, s->age, s->fraction);
//}
//
//int main()
//{
//	Stu s1 = {"张三", 20, 80.5};
//	Stu s2 = {"李四", 18, 92.0};
//	Print1(s1);//传值调用
//	Print2(&s2);//传址调用
//
//	return 0;
//}

//联合体
//联合体的声明
//union U
//{
//	char ch;
//	int a;
//};

//联合体⼤⼩的计算
//#include <stdio.h>
//
//union Un1
//{
//	char c[5];//1 8 1
//	int i;    //4 8 4
//};//整体大小是5，浪费3个字节补为4的倍数8
//
//union Un2
//{
//	short c[7];//2 8 2
//	int i;     //4 8 4
//};//整体大小是14，浪费两个字节补为4的倍数为16
//
//int main()
//{
//	//下⾯输出的结果是什么？
//	printf("%zd\n", sizeof(union Un1));//8
//	printf("%zd\n", sizeof(union Un2));//16
//
//	return 0;
//}

//用联合体实现判断大小端字节序的函数
//#include<stdio.h>
//
//union Un
//{
//	char ch;
//	int a;
//};
//
//int BigSmallEnds()
//{
//	union Un u;
//	u.a = 1;
//	if (u.ch == 1)
//	{
//		return 1;//小端
//	}
//	else
//	{
//		return 0;//大端
//	}
//}
//
//int main()
//{
//	if (BigSmallEnds() == 1)
//	{
//		printf("小端\n");
//	}
//	else
//	{
//		printf("大端\n");
//	}
//
//	return 0;
//}

//枚举类型的声明

//星期
//enum Week
//{
//	Monday,
//	Tuesday,
//	Wednesday,
//	Thursday,
//	Friday,
//	Saturday,
//	Sunday
//};
//
////性别
//enum Age
//{
//	man,
//	woman,
//	secrecy
//};
//
////游戏模式
//enum Mode
//{
//	peace,
//	Simple,
//	ordinary,
//	difficulty,
//};

//枚举类型的使⽤
//#include<stdio.h>
//
//enum Mode
//{
//	peace = 0,
//	Simple = 1,
//	ordinary = 2,
//	difficulty = 3
//};
//
//int main()
//{
//	enum Mode mode = peace;
//
//	return 0;
//}

//动态内存管理
//malloc和free
//#include<stdio.h>
//#include<stdlib.h>
//
//int main()
//{
//	//int* p = (int*)malloc(40);
//	int* p = (int*)malloc(sizeof(int) * 10);
//	if (p == NULL)
//	{
//		perror("malloc");
//		exit(-1);
//	}
//
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		*(p+i) = i + 1;
//	}
//
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d ", p[i]);
//	}
//
//	free(p);
//	p = NULL;//释放内存后及时置空，防止野指针问题
//
//	return 0;
//}

//calloc
//void* calloc (
//				size_t num, //需要开辟的元素个数
//				size_t size //每个元素的大小是多少(单位是字节)
//				);
//#include<stdio.h>
//#include<stdlib.h>
//
//int main()
//{
//	//malloc和calloc的区别就是
//	//malloc开辟好空间后不会对空间进行初始化
//	//calloc开辟好空间后会对空间初始化为0
//	int* pa = (int*)calloc(10, sizeof(int));
//	if (pa == NULL)
//	{
//		perror("calloc");
//		exit(-1);
//	}
//
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		*(pa + i) = i + 1;
//	}
//
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d ", pa[i]);
//	}
//
//	free(pa);
//	pa = NULL;
//
//	return 0;
//}

//realloc
//#include<stdio.h>
//#include<stdlib.h>
//#include<string.h>
//
//int main()
//{
//	int* pa = (int*)malloc(sizeof(int) * 10);
//	if (pa == NULL)
//	{
//		perror("malloc");
//		exit(-1);
//	}
//	memset(pa, 0, 40);
//
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		pa[i] = i + 1;
//	}
//
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d ", pa[i]);
//	}
//	printf("\n");
//
//	//进行扩容
//	int* tmp = (int*)realloc(pa, sizeof(int) * 20);
//	if (tmp == NULL)
//	{
//		perror("realloc");
//		exit(-1);
//	}
//
//	pa = tmp;
//	tmp = NULL;
//
//	memset(pa+10, 0, 40);
//
//	for (i = 10; i < 15; i++)
//	{
//		pa[i] = i + 1;
//	}
//
//	for (i = 0; i < 20; i++)
//	{
//		printf("%d ", pa[i]);
//	}
//	printf("\n");
//
//	free(pa);
//	pa = NULL;
//
//	return 0;
//}

//柔性数组
//柔性数组是配合动态内存管理使用的
//#include<stdio.h>
//#include<stdlib.h>
//
//struct S
//{
//	char ch;
//	int arr[0];//结构体的最后一个成员是一个数组并且数组的大小不写或写0，称为柔性数组
//};
//
//int main()
//{
//	struct S* ps = (struct S*)malloc(sizeof(struct S) + 20);//开辟了21个字节的空间，1个字节留给ch其他20个字节给arr使用
//	if (ps == NULL)
//	{
//		perror("malloc");
//		exit(-1);
//	}
//
//	ps->ch = 'w';
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		ps->arr[i] = i + 1;
//	}
//
//	printf("%c ", ps->ch);
//	for (i = 0; i < 5; i++)
//	{
//		printf("%d ", ps->arr[i]);
//	}
//	printf("\n");
//
//	//空间不够使用，进行扩容
//	struct S* tmp = (struct S*)realloc(ps, sizeof(struct S) + 40);
//	if (tmp == NULL)
//	{
//		perror("realloc");
//		exit(-1);
//	}
//	ps = tmp;
//	tmp = NULL;
//
//	for (i = 5; i < 10; i++)
//	{
//		ps->arr[i] = i + 1;
//	}
//
//	printf("%c ", ps->ch);
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d ", ps->arr[i]);
//	}
//	printf("\n");
//
//	free(ps);
//	ps = NULL;
//
//	return 0;
//}


//文件指针
//#include<stdio.h>
//
//int main()
//{
//	FILE* pf;//这就是一个文件指针
//
//	return 0;
//}

//⽂件的打开和关闭
//#include<stdio.h>
//#include<stdlib.h>
//
//int main()
//{
//	//打开文件
//	FILE* pf = fopen("test.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		exit(-1);
//	}
//	else
//	{
//		printf("打开成功\n");
//	}
//
//	//读/写文件
//
//
//	//关闭文件
//	fclose(pf);
//	pf = NULL;//fclose不会将指针置空，所以关闭文件后及时将指针置空
//
//	return 0;
//}

//⽂件顺序读写的库函数使用
//fgetc和fputc
//#include<stdio.h>
//#include<stdlib.h>
//
//int main()
//{
//	//往文件里写入26个英文字母
//	//打开文件
//	FILE* pf = fopen("test.txt", "w");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		exit(-1);
//	}
//
//	//写文件
//	int i = 0;
//	for (i = 'a'; i < 'z' + 1; i++)
//	{
//		fputc(i, pf);
//	}
//
//
//	//关闭文件
//	fclose(pf);
//	pf = NULL;
//	
//
//	return 0;
//}

//#include<stdio.h>
//#include<stdlib.h>
//
//int main()
//{
//	//从文件里读入字符
//	//打开文件
//	FILE* pf = fopen("test.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		exit(-1);
//	}
//
//	//读文件
//	char ch = 0;
//	while ((ch = fgetc(pf)) != EOF)
//	{
//		printf("%c ", ch);
//	}
//
//
//	//关闭文件
//	fclose(pf);
//	pf = NULL;
//
//
//	return 0;
//}

//fputs和fgets
//#include<stdio.h>
//#include<stdlib.h>
//
//int main()
//{
//	//打开指针
//	FILE* pf = fopen("test.txt", "w");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		exit(-1);
//	}
//
//	//写文件
//	char* str = "hello world";
//	fputs(str, pf);
//
//	//关闭文件
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}

//#include<stdio.h>
//#include<stdlib.h>
//
//int main()
//{
//	//打开指针
//	FILE* pf = fopen("test.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		exit(-1);
//	}
//
//	//写文件
//	char str[8] = {0};
//	fgets(str, 8, pf);
//	printf("%s\n", str);
//
//	//关闭文件
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}

//fprintf和fscanf
//#include<stdio.h>
//#include<stdlib.h>
//
//struct S
//{
//	char ch;
//	int a;
//	double pai;
//};
//
//int main()
//{
//	//往data.txt文件里写入数据
//	//打开文件
//	FILE* pf = fopen("data.txt", "w");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		exit(-1);
//	}
//
//	//写文件
//	struct S s = {'b', 100, 3.14};
//	fprintf(pf, "%c %d %lf", s.ch, s.a, s.pai);
//
//
//	//关闭文件
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}

//#include<stdio.h>
//#include<stdlib.h>
//
//struct S
//{
//	char ch;
//	int a;
//	double pai;
//};
//
//int main()
//{
//	//从data.txt文件里读入数据到结构体里
//	//打开文件
//	FILE* pf = fopen("data.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		exit(-1);
//	}
//
//	//读文件
//	struct S s = { 0 };
//	fscanf(pf, "%c %d %lf", &(s.ch), &(s.a), &(s.pai));
//	printf("%c %d %lf\n", s.ch, s.a, s.pai);
//
//	//关闭文件
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}

//sprintf和sscanf
//#include<stdio.h>
//#include<stdlib.h>
//
//struct S
//{
//	char str[10];
//	int a;
//	double pai;
//};
//
//int main()
//{
//	struct S s1 = { "hello", 10, 3.14 };
//	char str[30] = { 0 };
//	//将结构体s里的数据转换成字符串存储在str里
//	sprintf(str, "%s %d %lf", s1.str, s1.a, s1.pai);
//	printf("字符串: %s\n", str);
//
//	//将字符串str的数据转换成对应格式的数据放入s2结构体里
//	struct S s2 = { 0 };
//	sscanf(str, "%s %d %lf", s2.str, &(s2.a), &(s2.pai));
//	printf("结构体: %s %d %lf\n", s2.str, s2.a, s2.pai);
//	
//
//	return 0;
//}

//⽂件的随机读写
//fseek和ftell和rewind
#include<stdio.h>
#include<stdlib.h>

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		exit(-1);
	}

	//读文件,test.txt里存储的内容是abcdef
	char ch = fgetc(pf);
	printf("%c", ch);
	//读了一个字符后，文件指针现在指向b，但我不想都b我要读d
	//fseek(pf, 3, SEEK_SET);//从开头开始偏移
	int i = ftell(pf);
	printf("当前文件指针的偏移量：%d\n", i);
	fseek(pf, 2, SEEK_CUR);//从当前文件指针处开始偏移
	//fseek(pf, -3, SEEK_END);//从文件末尾开始偏移
	ch = fgetc(pf);
	printf("%c", ch);

	//现在不知道当前文件指针指向哪了，我要将文件指针回到开头,用rewind库函数
	rewind(pf);
	ch = fgetc(pf);
	printf("%c", ch);

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}